package com.outsider.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.outsider.note.dao.TextNote;
import com.outsider.note.dao.VoiceNote;
import com.outsider.note.entity.BaseNote;
import com.outsider.note.task.NoteTimerTask;
import com.outsider.note.task.TextNoteTimerTask;
import com.outsider.note.task.VoiceNoteTimerTask;
import com.outsider.product.service.ProductService;

public class ScheduleUtil {
	private ScheduledExecutorService ses;
	private HashMap<BaseNote, ScheduledFuture> noteMap;
	private List<NoteTimerTask> noteTaskList;
	private final Logger logger = Logger.getLogger("");
	private static ScheduleUtil single;

	// 单例
	public static ScheduleUtil getScheduleUtil() {
		if (single == null)
			synchronized (ScheduleUtil.class) {
				if (single == null)
					single = new ScheduleUtil();
			}
		return single;
	}

	private ScheduleUtil() {
		ses = Executors.newScheduledThreadPool(3);
		noteMap = new HashMap<BaseNote, ScheduledFuture>();
		noteTaskList = new ArrayList<NoteTimerTask>();
		initNote();
		initSes();
		addNewsTask();
		addMovieTask();
        addProductTask();
	}

	private void addProductTask() {
		ses.scheduleWithFixedDelay(new Runnable() {
			public void run() {
				ProductService productService=new ProductService();
				productService.updateRecord(null);
				logger.info("update product record success");
			}
		}, 0, 12,TimeUnit.HOURS);
		
	}

	private void initSes() {
		noteTaskList.forEach(task -> {
			addTask(task);
		});

	}

	private void initNote() {
		initTextNote();
		initVoiceNote();
		Collections.sort(noteTaskList);
	}

	private void initVoiceNote() {
		List<VoiceNote> noteList = VoiceNote.dao.findNotExpiredNote();
		noteList.forEach(note -> {
			VoiceNoteTimerTask voiceNoteTimerTask = new VoiceNoteTimerTask(note);
			noteTaskList.add(voiceNoteTimerTask);
		});

	}

	private void initTextNote() {
		List<TextNote> noteList = TextNote.dao.findNotExpiredNote();
		noteList.forEach(note -> {
			TextNoteTimerTask noteTimerTask = new TextNoteTimerTask(note);
			noteTaskList.add(noteTimerTask);
		});
	}

	public void addTask(NoteTimerTask task) {
		long delay = task.getCallDate().getTime() - new Date().getTime();
		delay = delay / 1000L;
		ScheduledFuture sf = ses.schedule(task, delay, TimeUnit.SECONDS);
		noteMap.put(task.getNote(), sf);
		if (task.getNote() instanceof VoiceNote)
			logger.info("VoiceNote ID:" + task.getNote().getID() + " schedule success " + delay);
		else if (task.getNote() instanceof TextNote)
			logger.info("TextNote ID:" + task.getNote().getID() + " schedule success delay " + delay);
	}

	public void deleteTask(BaseNote note) {
		ScheduledFuture sf = noteMap.get(note);
		if (sf != null && sf.cancel(true))
			logger.info("note has been cancel " + note.getID());

	}

	private void addNewsTask() {
		ses.scheduleWithFixedDelay(ZhiHuUtil.getZhiHuTask(), 0, 24, TimeUnit.HOURS);
		ses.scheduleWithFixedDelay(AcfunUtil.getAcfunTask(), 0, 8, TimeUnit.HOURS);
		ses.scheduleWithFixedDelay(PhoenixNewsUtil.getPhoenixNewsTask(), 0, 6, TimeUnit.HOURS);
	}

	private void addMovieTask() {
		ses.scheduleWithFixedDelay(MovieUtil.getMovieTask(), 0, 24, TimeUnit.HOURS);
	}
}
